package com.e3.basdoc.region.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.e3.basdoc.region.dao.RegionDAO;
import com.e3.basdoc.region.entity.RegionEntity;
import com.e3.basdoc.region.model.RegionModel;
import com.e3.basdoc.region.service.RegionCacheManager;
import com.e3.basdoc.region.service.RegionService;
import com.e3.core.base.DAOHelper;
import com.e3.core.base.ServiceException;
import com.e3.core.base.SuperService;
import com.e3.web.core.model.SuperModel;

/**
 * Description: <br>
 * 
 * @author: <a href="mailto:senton1101@126.com">TianXiangdong</a> 2010-8-6
 */
public class RegionServiceImpl extends SuperService implements RegionService {

	private RegionDAO regionDAO;
	
	private RegionDAO getRegionDAO() {
		if (regionDAO == null) {
			regionDAO = DAOHelper.createDAOInstance(RegionDAO.class);
		}
		return regionDAO;
	}

	// 新建Region
	/* (non-Javadoc)
	 * @see com.e3.basdoc.region.service.impl.RegionService#newRegion(com.e3.basdoc.region.model.RegionModel)
	 */
	public RegionModel newRegion(RegionModel regionModel) throws ServiceException {
		validateRegion(regionModel);
		checkRegionExisted(regionModel);

		RegionEntity region = regionModelToEntity(regionModel, null);
		getRegionDAO().persist(region);
		
		regionModel.setId(region.getId());
		RegionCacheManager.INSTANCE.put(regionModel);
		
		return regionModel;
	}

	// 修改Region
	/* (non-Javadoc)
	 * @see com.e3.basdoc.region.service.impl.RegionService#modifyRegion(com.e3.basdoc.region.model.RegionModel)
	 */
	public RegionModel modifyRegion(RegionModel regionModel) throws ServiceException {
		validateRegion(regionModel);

//		String strId = regionModel.getId();
//		long id = Long.parseLong(strId == null ? "0" : strId);
		
		long id = regionModel.getId();

		RegionEntity entity = getRegionDAO().getById(RegionEntity.class, id);
		if (entity == null) {
			newRegion(regionModel);
			return regionModel;
		}

		String oldCode = entity.getCode();
		if (!oldCode.equals(regionModel.getCode())) {
			checkRegionExisted(regionModel);
		}

		regionModelToEntity(regionModel, entity);

		getRegionDAO().merge(entity);
		RegionCacheManager.INSTANCE.put(regionModel);
		return regionModel;
	}

	// 检查code和name是否为空
	private void validateRegion(RegionModel regionModel) throws ServiceException {
		String code = regionModel.getCode();
		String name = regionModel.getName();

		if (code == null || code.trim().length() == 0 || name == null || name.trim().length() == 0) {
			throw new ServiceException("请设置地区的编码和名称。");
		}
	}

	// 检查是否存在code为参数regionCode的Region
	/* (non-Javadoc)
	 * @see com.e3.basdoc.region.service.impl.RegionService#checkRegionExisted(com.e3.basdoc.region.model.RegionModel)
	 */
	public void checkRegionExisted(RegionModel regionModel) throws ServiceException {
		if (regionModel == null) {
			return;
		}

		String code = regionModel.getCode();
		String name = regionModel.getName();
		RegionEntity entity = getRegionDAO().getRegionByCode(code);
		if (entity != null) {
			throw new ServiceException("编码为'" + code + "',名称为'" + name + "'已经存在，请设置新的编码和名称。");
		}
	}

	// 删除多个region
	/* (non-Javadoc)
	 * @see com.e3.basdoc.region.service.impl.RegionService#deleteRegions(java.util.List)
	 */
	public void deleteRegions(List<RegionModel> regionModels) throws ServiceException {
		if (regionModels == null || regionModels.isEmpty()) {
			return;
		}
		Long[] ids = getIds(regionModels);
		deleteRegionByIds(ids);
	}
	/* (non-Javadoc)
	 * @see com.e3.sysmg.security.service.ISecurityService#deleteModules(java.util.List)
	 */
	public void deleteRegionByIds(Long[] moduleIds) throws ServiceException{
		if(moduleIds==null||moduleIds.length==0){
			return;
		}
		
		List<Long> delIds = getDeletedRegionIds(moduleIds);
		Long[] ids = new Long[delIds.size()];
		delIds.toArray(ids);
		getRegionDAO().deleteRegionByIds(ids);
		
		RegionCacheManager.INSTANCE.remove(delIds);
	}
	
	private List<Long> getDeletedRegionIds(Long[] regionIds) throws ServiceException{
		if(regionIds==null||regionIds.length==0){
			return null;
		}
		List<Long> ids = new ArrayList<Long>();
		for (long id : regionIds) {
			if(!ids.contains(id)){
				ids.add(id);
			}
		}
		List<Long> childrenIds = getRegionDAO().getChildrenIds(regionIds);
		if(childrenIds!=null&&childrenIds.size()>0){
			Long[] cIds = new Long[childrenIds.size()];
			childrenIds.toArray(cIds);
			return getDeletedRegionIds(cIds);
		}
		return ids; 
	}
	
	private Long[] getIds(List<? extends SuperModel> models) {
		if (models == null || models.isEmpty()) {
			return null;
		}
		Long[] ids = new Long[models.size()];
		for (int i = 0; i < models.size(); i++) {
			ids[i] = models.get(i).getId();
		}
		return ids;
	}

	private RegionEntity regionModelToEntity(RegionModel regionModel, RegionEntity entity) {
		RegionEntity region = super.modelToEntity(RegionEntity.class, regionModel, entity);

		region.setCode(regionModel.getCode());
		region.setName(regionModel.getName());
		region.setParentId(regionModel.getParentId());
		region.setEnglishName(regionModel.getEnglishName());
		region.setZipcode(regionModel.getZipcode());

		return region;
	}

}
